using System;
using System.Collections;
using Castle.MonoRail.TestSupport;
using NHibernate;
using NUnit.Framework;
using Rhino.Mocks;
using Rhino.Mocks.Constraints;
using DecisionesInteligentes.iEvalua.Web.Controllers;
using DecisionesInteligentes.iEvalua.Web.Services;
using DecisionesInteligentes.iEvalua.Models;
using DecisionesInteligentes.iEvalua.Helpers;
using DecisionesInteligentes.iEvalua.Tests.Helpers;

namespace DecisionesInteligentes.iEvalua.Tests.Controllers {
	[TestFixture]
	public class RolesControllerTestCase : ControllerARMockTestCase<RolesController, Role>
	{
		protected override void SetupApplication()
		{
			using(new MockScope(session))
			{
				Application application = controller.Application;
				
				Assert.IsNotNull(application);
				Assert.AreEqual(application.Id, 1);
			}
		}
		
		public override void SetUp()
		{
			base.SetUp();
			
			controller = new RolesController();
			
			DoApplicationSetup();
		}
		
		[Test]
		public void Show_Roles_List()
		{
			ShowList(ModelMocks.GetRole());
		}
		
		protected override void List_SUT()
		{
			PrepareController(controller, "", "Roles", "Index");
			controller.Index();
	
			Assert.IsNotNull(controller.PropertyBag["entities"]);
		}
		
		
		[Test]
		public void Create_New_Role()
		{
			Create();
		}
		
		protected override void Create_SUT()
		{
			Role role = ModelMocks.GetRole();
			role.Application = null;
			PrepareController(controller, "", "Roles", "Create");
			controller.Create(role);
	
			Assert.AreEqual("A new Role has been created", controller.Flash["message"]);
			Assert.AreEqual("/Roles/Edit.rails?id=1&", Response.RedirectedTo);
		}
		
		[Test]
		public void Create_Invalid_New_Role()
		{
			CreateInvalid();
		}
		
		protected override void Create_Invalid_SUT()
		{
			Role role = ModelMocks.GetRole();
			role.Name = null;
			
			PrepareController(controller, "", "Roles", "Create");
			controller.Create(role);
	
			Assert.AreEqual("Role has some invalid data", controller.Flash["message"]);
			Assert.IsNotNull(controller.PropertyBag["entity"]);
			Assert.IsNotNull(controller.Flash["error"]);
			Assert.AreEqual("Name cannot be empty", ((string[])controller.Flash["error"])[0]);
			Assert.AreEqual("/Roles/New.rails", Response.RedirectedTo);
		}
		
		[Test]
		public void Create_Fail_New_Role()
		{
			CreateFail();
		}
		
		protected override void Create_Fail_SUT()
		{
			PrepareController(controller, "", "Roles", "Create");
			controller.Create(ModelMocks.GetRole());
			
			Assert.AreEqual("Role was not saved due some errors.", controller.Flash["message"]);
			Assert.IsNotNull(controller.PropertyBag["entity"]);
			Assert.AreEqual("Could not perform Create for Role", ((string[])controller.Flash["error"])[0]);
			Assert.AreEqual("/Roles/New.rails", Response.RedirectedTo);
		}
		
		[Test]
		public void ViewEdit_Existing_Role()
		{
			ViewEditExisting(ModelMocks.GetRole());
		}
		
		protected override void View_Edit_Existing_SUT()
		{
			PrepareController(controller, "", "Roles", "View");
			controller.View(1);
			
			Assert.IsNull(controller.Flash["message"]);
			Assert.IsNotNull(controller.PropertyBag["entity"]);
			Assert.IsNull(controller.Flash["error"]);
		}
		
		[Test]
		public void ViewEdit_Non_Existing_Role()
		{
			ViewEditNonExisting(ModelMocks.GetRole());
		}
		
		protected override void View_Edit_NonExisting_SUT()
		{
			PrepareController(controller, "", "Roles", "View");
			controller.View(0);
			
			Assert.AreEqual("Failed to load Role", controller.Flash["message"]);
			Assert.IsNull(controller.PropertyBag["entity"]);
			Assert.AreEqual("Role not found", ((string[])controller.Flash["error"])[0]);
			Assert.AreEqual("/Roles/Index.rails", Response.RedirectedTo);
		}
		
		[Test]
		public void ViewEdit_Load_Fail_Exception()
		{
			ViewEditLoadFailException(ModelMocks.GetRole());
		}
		
		protected override void View_Edit_Load_Fail_Exception_SUT()
		{
			PrepareController(controller, "", "Roles", "View");
			controller.View(1);
			
			Assert.AreEqual("Failed to load Role", controller.Flash["message"]);
			Assert.IsNull(controller.PropertyBag["entity"]);
			Assert.AreEqual("Could not perform FindByPrimaryKey for Role. Id: 1", 
				((string[])controller.Flash["error"])[0]);
			Assert.AreEqual("/Roles/Index.rails", Response.RedirectedTo);
		}
		
		[Test]
		public void Save_Existing_Role()
		{
			SaveExisting(ModelMocks.GetRole());
		}
		
		protected override void Save_Existing_SUT()
		{
			PrepareController(controller, "", "Roles", "Save");
			controller.Save(ModelMocks.GetRole());
	
			Assert.AreEqual("Role has been saved", controller.Flash["message"]);
			Assert.IsNull(controller.PropertyBag["entity"]);
			Assert.IsNull(controller.Flash["error"]);
			Assert.AreEqual("/Roles/Edit.rails?id=1&", Response.RedirectedTo);
		}
		
		[Test]
		public void Save_Invalid_Role()
		{
			SaveInvalid();
		}
		
		protected override void Save_Invalid_SUT()
		{
			Role role = ModelMocks.GetRole();
			role.Name = null;
			
			PrepareController(controller, "", "Roles", "Save");
			controller.Save(role);
	
			Assert.AreEqual("Role has some invalid data", controller.Flash["message"]);
			Assert.IsNotNull(controller.PropertyBag["entity"]);
			Assert.AreEqual("Name cannot be empty", ((string[])controller.Flash["error"])[0]);
			Assert.AreEqual("/Roles/Edit.rails", Response.RedirectedTo);
		}
		
		[Test]
		public void Save_Exception()
		{
			SaveException();
		}
		
		protected override void Save_Exception_SUT()
		{
			PrepareController(controller, "", "Roles", "Save");
			controller.Save(ModelMocks.GetRole());
		
			Assert.AreEqual("Role was not saved due some errors.", controller.Flash["message"]);
			Assert.IsNotNull(controller.PropertyBag["entity"]);
			Assert.AreEqual("Could not perform Update for Role", 
				((string[])controller.Flash["error"])[0]);
			Assert.AreEqual("/Roles/Edit.rails", Response.RedirectedTo);
		}
	}
}